//
//  VIPLiveVideoManager.m
//  TTProduct
//
//  Created by My mac on 2018/8/20.
//  Copyright © 2018年 TTProduct. All rights reserved.
//

#import "VIPLiveVideoManager.h"
#import "VIPAgoraVideoManager.h"
#import "VIPZegoVideoManager.h"
#import "VIPSignalingHelper.h"

#import "VIPRoomModel.h"
#import "VIPSignalManager.h"
#import "VIPPCH.h"

@interface VIPLiveVideoManager()

@property (nonatomic, strong) NSMutableDictionary *videoCanvasDict;

@property (nonatomic, strong) VIPRoomModel *room;

@property (nonatomic, strong) VIPBaseVideoManager *videoManager;
@property (strong, nonatomic) VIPSignalManager *signalManager;

@end

@implementation VIPLiveVideoManager




//- (void)setRemoteDidJoin:(LiveRemoteDidJoined)remoteDidJoin {
//    _remoteDidJoin = remoteDidJoin;
//    self.videoManager.remoteDidJoin = remoteDidJoin;
//}
//
//- (void)setRemoteDidOffline:(LiveDidOffline)remoteDidOffline {
//    _remoteDidOffline = remoteDidOffline;
//    self.videoManager.remoteDidOffline = remoteDidOffline;
//}
//
//- (void)setTokenDidFailure:(LiveTokenDidFailure)tokenDidFailure {
//    _tokenDidFailure = tokenDidFailure;
//    self.videoManager.tokenDidFailure = tokenDidFailure;
//}

- (void)bindingRoomInfo:(VIPRoomModel *)room {
    _room = room;
}

// 进入房间
- (void)joinLiveVideo:(NSView *)localView {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(joinLiveVideo:)]) {
        return;
    }
    
    [self setupMakeLiveManager:self.room.rtcModel localView:localView];

    [self.videoManager joinLiveVideo:localView];
}

- (void)setupMakeLiveManager:(VIPBaseRTCModel *)rtc localView:(NSView *)view {
    _videoManager = nil;
    _videoCanvasDict = nil;
    self.videoCanvasDict[@(self.room.uid)] = view;
    
    if (rtc.type == VIPRTCServerAgora) {
        self.videoManager = [VIPAgoraVideoManager shareManager];
    }
    
    if (rtc.type == VIPRTCServerZego) {
        self.videoManager = [VIPZegoVideoManager shareManager];
    }
    
    if (!_videoManager) { return; }
    
    self.videoManager.rtc = rtc;
    self.videoManager.uid = _room.uid;
    
    [self setupMakeLiveCallback];
}

- (void)setupMakeLiveCallback {
    // 实时创建View
    [self setRealTimeCanvasView];
    
    // 本地即将进入回调
    [self setLocalWillJoin];
    
    // 本地已经进入回调
    [self localDidJoined];
    
    // 本地重新进入回调
    [self setLocalReJoined];
    
    // 本地第一帧回调
    [self setLocalFirstVideoDecoded];
    
    // 远端进入回调
    [self setRemoteDidJoined];
    
    // 远端第一帧回调
    [self setRemoteFirstVideoDecoded];
    
    // 视频(关闭/打开)回调
    [self setDidVideoMuted];
   
    // 音频(关闭/打开)回调
    [self setDidAudioMuted];
    
    // 视频质量回调
    [self setVideoNetworkQuality];
    
    // 音频质量回调
    [self setAudioVolumeIndication];
    
    // 有用户离开
    [self setRemoteDidOffline];
    
    // Token已经失效
    [self setTokenDidFailure];
}

// 实时创建View
- (void)setRealTimeCanvasView {
    WS(weakSelf)
    [self.videoManager setRealTimeRemoteView:^(NSUInteger uid) {
        NSLog(@"setRealTimeRemoteView: uid:%lu", uid);
        [VIPWrite writeLogWithFormat:@"%s, uid:%ld", __func__, uid];
        
        [weakSelf remoteDidJoined:uid];
    }];
}

- (void)remoteDidJoined:(NSUInteger)uid {
    bool isExist = [self isInsiderInRoom:uid];
    WS(weakSelf)
    void(^remoteDidJoinBlock)(void) = ^{
        VIPVideoCanvasView *remoteView = [weakSelf videoCanvasView:uid];
        NSLog(@"%s ---- %d", __func__, remoteView.online);
        if (!weakSelf.videoManager.remoteViewHandler) { return; }
        weakSelf.videoManager.remoteViewHandler(remoteView.contentView);
    };

    // 如果有远端用户直接
    if (isExist) {
        remoteDidJoinBlock();
        return;
    }

    // 更新学生列表
    [VIPAPIService roomMembers:self.room.pkClass pkSyllabus:self.room.pkSyllabus block:^(BOOL result, NSMutableArray * _Nonnull members) {
        weakSelf.room.students = members;
        bool isExist = [weakSelf isInsiderInRoom:uid];
        if (!isExist) { return; }
        remoteDidJoinBlock();
    }];
}

// 判断远端是否是教室内部成员
- (BOOL)isInsiderInRoom:(NSUInteger)uid {
    bool isExist = (uid == self.room.teacher.uid);
    if (isExist) { return isExist; }
    NSArray *students = self.room.students;
    for (int i = 0; i < students.count; i++) {
        VIPUserModel *student = students[i];
        if (uid != student.uid) { continue; }
        isExist = YES;
        break;
    }
    return isExist;
}

// 本地正在进入回调
- (void)setLocalWillJoin {
    WS(weakSelf)
    [self.videoManager setLocalWillJoin:^(NSUInteger uid) {
        VIPVideoCanvasView *localView = weakSelf.videoCanvasDict[@(uid)];
        localView.livingType = VIPLivingTypeOnline | VIPLivingTypeOnlineJoin;
    }];
}

// 本地已经进入回调
- (void)localDidJoined {
    WS(weakSelf)
    [self.videoManager setLocalDidJoined:^(NSUInteger uid) {
        VIPVideoCanvasView *localView = weakSelf.videoCanvasDict[@(uid)];
        localView.livingType = VIPLivingTypeOnline | VIPLivingTypeOnlineJoined;
    }];
}

// 本地重新进入回调
- (void)setLocalReJoined {
    WS(weakSelf)
    [self.videoManager setLocalReJoined:^(NSUInteger uid) {
        
    }];
}

// 本地第一帧回调
- (void)setLocalFirstVideoDecoded {
    WS(weakSelf)
    [self.videoManager setLocalFirstVideoDecoded:^(NSUInteger uid) {
        VIPVideoCanvasView *localView = weakSelf.videoCanvasDict[@(uid)];
        localView.livingType = VIPLivingTypeOnline | VIPLivingTypeOnlineCamera;
    }];
}

// 远端进入回调
- (void)setRemoteDidJoined {
    WS(weakSelf)
    [self.videoManager setRemoteDidJoined:^(NSUInteger uid) {
        VIPVideoCanvasView *remoteView = weakSelf.videoCanvasDict[@(uid)];
        remoteView.livingType = VIPLivingTypeOnline | VIPLivingTypeOnlineJoined;
    }];
}

// 远端第一帧回调
- (void)setRemoteFirstVideoDecoded {
    WS(weakSelf)
    [self.videoManager setRemoteFirstVideoDecoded:^(NSUInteger uid) {
        VIPVideoCanvasView *remoteView = weakSelf.videoCanvasDict[@(uid)];
        remoteView.livingType = VIPLivingTypeOnline | VIPLivingTypeOnlineCamera;
    }];
}

// 视频(关闭/打开)回调
- (void)setDidVideoMuted {
    WS(weakSelf)
    [self.videoManager setDidVideoMuted:^(BOOL muted, NSUInteger uid) {
        VIPVideoCanvasView *remoteView = weakSelf.videoCanvasDict[@(uid)];
        VIPLivingType livingType = remoteView.livingType;
        if (muted) {
            livingType = livingType & (~VIPLivingTypeOnlineCamera);
        } else {
            livingType = livingType | VIPLivingTypeOnlineCamera;
        }
        remoteView.livingType = livingType;
    }];
}

// 音频(关闭/打开)回调
- (void)setDidAudioMuted {
    WS(weakSelf)
    [self.videoManager setDidAudioMuted:^(BOOL muted, NSUInteger uid) {
        VIPVideoCanvasView *remoteView = weakSelf.videoCanvasDict[@(uid)];
        remoteView.closeMicrophone = !muted;
    }];
}

// 视频质量回调
- (void)setVideoNetworkQuality {
    WS(weakSelf)
    [self.videoManager setVideoNetworkQuality:^(NSUInteger uid, NSInteger level) {
        VIPVideoCanvasView *remoteView = weakSelf.videoCanvasDict[@(uid)];
        remoteView.networkLevel = level;
    }];
}

// 音频质量回调
- (void)setAudioVolumeIndication {
    WS(weakSelf)
    [self.videoManager setAudioVolumeIndication:^(NSUInteger uid, NSInteger value) {
        VIPVideoCanvasView *remoteView = weakSelf.videoCanvasDict[@(uid)];
        remoteView.volume = value;
    }];
}

///  0:0
- (void)remoteDidOffline:(NSUInteger)uid {
    
    [self removeVideoCanvasView:uid];
    if (!self.remoteDidOffline) return;
    self.remoteDidOffline(uid);
}

// 有用户离开
- (void)setRemoteDidOffline {
    WS(weakSelf)
    [self.videoManager setRemoteDidOffline:^(NSUInteger uid) {
        VIPVideoCanvasView *remoteView = weakSelf.videoCanvasDict[@(uid)];
        VIPLivingType livingType = remoteView.livingType;
        livingType = livingType & (~VIPLivingTypeOnline);
        remoteView.livingType = livingType;
        
    }];
}

// Token已经失效
- (void)setTokenDidFailure {
    WS(weakSelf)
    [self.videoManager setTokenDidFailure:^{
        
    }];
}

// 切换助教/ 老师 0:0
- (void)switchRole {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
//    if (![self.videoManager respondsToSelector:@selector(switchRole:)]) {
//        return;
//    }
    // NSUInteger uid = self.room.teacher.uid;
    // [self.videoManager ]
    // [self.videoManager switchRoleInView:view uid:uid];
}

// 退出房间
- (void)quitLiveVideo:(LiveQuitRoom)quitLiveVideoEvent {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(quitLiveVideo:)]) { return; }
    WS(weakSelf)
    [self.videoManager quitLiveVideo:^{
        [[VIPSignalManager shareManager] leaveRoom];
        for (id key in weakSelf.videoCanvasDict) {
            NSView *accountView = weakSelf.videoCanvasDict[key];
            //[weakSelf videoCanvasView:[key integerValue]];
            [accountView removeFromSuperview];
        }
        if (!quitLiveVideoEvent) { return; }
        quitLiveVideoEvent();
    }];
}

// 切换视频分辨率(大流/小流)
- (void)setRemoteVideoStream:(NSUInteger)uid type:(VIPVideoStreamType)type {
    [VIPWrite writeLogWithFormat:@"%s, uid:%ld, type:%ld", __func__, uid, (long)type];
    
    if (![self.videoManager respondsToSelector:@selector(setRemoteVideoStream:type:)]) return ;
    [self.videoManager setRemoteVideoStream:uid type:type];
}

// 本地视频采集 (NO:打开/ YES:关闭)
- (void)enableLocalVideoStream:(BOOL)open {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(enableLocalVideoStream:)]) {
        return;
    }
    [self.videoManager enableLocalVideoStream:open];
}

// 本地视频推流 (NO:打开/ YES:关闭)
- (void)pushLocalVideoStream:(BOOL)muted {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(pushLocalVideoStream:)]) {
        return;
    }
    [self.videoManager pushLocalVideoStream:muted];
}

// 本地音频推流 (NO:打开/ YES:关闭)
- (void)pushLocalAudioStream:(BOOL)muted {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(pushLocalAudioStream:)]) {
        return;
    }
    [self.videoManager pushLocalAudioStream:muted];
}

// 远端视频拉流个人 (NO:打开/ YES:关闭)
- (void)pullRemoteVideoUID:(NSUInteger)uid muted:(BOOL)muted {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(pullRemoteVideoUID:muted:)]) {
        return;
    }
    [self.videoManager pullRemoteVideoStream:uid muted:muted];
}

// 远端音频拉流个人 (NO:打开/ YES:关闭)
- (void)pullRemoteAudioUID:(NSUInteger)uid muted:(BOOL)muted {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(pullRemoteAudioUID:muted:)]) {
        return;
    }
    [self.videoManager pullRemoteAudioStream:uid muted:muted];
}

// 远端视频拉流全部 (NO:打开/ YES:关闭)
- (void)pullRemoteVideoStreamAll:(BOOL)muted {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(pullRemoteVideoStreamAll:)]) {
        return;
    }
    [self.videoManager pullRemoteVideoStreamAll:muted];
}

// 远端音频拉流全部 (NO:打开/ YES:关闭)
- (void)pullRemoteAudioStreamAll:(BOOL)muted {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(pullRemoteAudioStreamAll:)]) {
        return;
    }
    [self.videoManager pullRemoteAudioStreamAll:muted];
}

// 设置美颜效果选项
- (void)setBeautyEffect:(BOOL)enable {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(setBeautyEffect:)]) {
        return;
    }
    [self.videoManager setBeautyEffect:enable];
}

// iPhone
#if TARGET_OS_IPHONE
// 切换前置摄像头
- (void)switchCamera {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    if (![self.videoManager respondsToSelector:@selector(switchCamera)]) {
        return;
    }
    [self.videoManager switchCamera];
}

#endif

// 屏幕共享
// 全屏
- (int)sharedFullScreen {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    int result = 0;
    if ([self.videoManager respondsToSelector:@selector(sharedFullScreen)]) {
        result = [self.videoManager sharedFullScreen];
    }
    return result;
}

// 指定窗口
- (int)sharedScreenWindowId:(NSUInteger)windowId {
    [VIPWrite writeLogWithFormat:@"%s - windowID:%ld", __func__, (long)windowId];
    
    int result = 0;
    if ([self.videoManager respondsToSelector:@selector(sharedScreenWindowId:)]) {
        result = [self.videoManager sharedScreenWindowId:windowId];
    }
    return result;
}

- (void)removeVideoCanvasView:(NSUInteger)uid {
    [self.videoCanvasDict removeObjectForKey:@(uid)];
}

- (VIPVideoCanvasView *)videoCanvasView:(NSUInteger)uid {
    VIPVideoCanvasView *videoCanvasView = self.videoCanvasDict[@(uid)];
    
    if (!videoCanvasView) {
        videoCanvasView = [VIPVideoCanvasView new];
        videoCanvasView.livingType = VIPLivingTypeOffline;
        self.videoCanvasDict[@(uid)] = videoCanvasView;
        videoCanvasView.locationtType = VIPLiveLocationTypeRemote;
    }
    
    return videoCanvasView;
}

- (int)stopScreenCapture {
    [VIPWrite writeLogWithFormat:@"%s", __func__];
    
    int result = 0;
    if (![self.videoManager respondsToSelector:@selector(stopScreenCapture)]) {
        result = [self.videoManager stopScreenCapture];
    }
    return result;
}

- (VIPSignalManager *)signalManager {
    if (!_signalManager) {
        _signalManager = [VIPSignalManager shareManager];
    }
    return _signalManager;
}

- (NSMutableDictionary *)videoCanvasDict {
    if (!_videoCanvasDict) {
        _videoCanvasDict = [NSMutableDictionary dictionary];
    }
    return _videoCanvasDict;
}

static VIPLiveVideoManager* _instance = nil;
+ (instancetype)shareManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:NULL] init];
    });
    return _instance ;
}

+ (id)allocWithZone:(struct _NSZone *)zone {
    return [VIPLiveVideoManager shareManager];
}

- (id)copyWithZone:(struct _NSZone *)zone {
    return [VIPLiveVideoManager shareManager];
}

@end
